#define LOG_TAG "NRF24L0X"

#include "string.h"
#include "stdio.h"

#include "drv_nrf24l0x.h"

static uint8_t nrf_tx_buf[TX_PLOAD_WIDTH + 1];
static uint8_t nrf_rx_buf[RX_PLOAD_WIDTH + 1];

static nrf24l0x_device_t nrf24l0x_device = {
    .working_mode = NRF24L0X_MODE_TX,
};

__weak uint8_t nrf24l0x_irq_pin_get(void)
{
    return 0;
}

__weak int32_t nrf24l0x_cs_ctrl(uint8_t ctrl)
{
    return 0;
}

__weak int32_t nrf24l0x_ce_ctrl(uint8_t ctrl)
{
    return 0;
}

__weak int32_t nrf24l0x_transfer_data(uint8_t *tx_data, uint8_t *rx_data, uint8_t len)
{
    return 0;
}

uint8_t nrf24l0x_status_get(void)
{
    uint8_t temp   = 0xFF;
    uint8_t status = 0;

    nrf24l0x_transfer_data(&temp, &status, 1);

    return status;
}

void nrf24l0x_status_clr(uint8_t status)
{
    nrf_tx_buf[0] = NRF24L0X_WRITE_REG + STATUS;
    nrf_tx_buf[1] = status;
    nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, 2);
}

// 启动NRF24L01发送一次数据
// txbuf:待发送数据首地址
// 返回值:0，接收完成；其他，错误代码
uint8_t nrf24l0x_rx_packet(uint8_t *rxbuf)
{
    uint8_t status;

    status = nrf24l0x_status_get();
    nrf24l0x_status_clr(status);

    // 接收到数据
    if (status & RX_OK) {
        memset(nrf_tx_buf, 0xFF, sizeof(nrf_tx_buf));
        nrf_tx_buf[0] = NRF24L0X_RD_RX_PLOAD;
        nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, RX_PLOAD_WIDTH + 1);   // 读取数据
        memcpy(rxbuf, &nrf_rx_buf[1], RX_PLOAD_WIDTH);

        nrf_tx_buf[0] = NRF24L0X_FLUSH_RX;
        nrf_tx_buf[1] = 0xFF;
        nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, 2);   // 清除RX FIFO寄存器

        return 0;
    }

    return 1;   // 没收到任何数据
}


// 启动NRF24L01发送一次数据
// txbuf:待发送数据首地址
// 返回值:发送完成状况
uint8_t nrf24l0x_tx_packet(uint8_t *txbuf)
{
    uint8_t status;

    nrf24l0x_ce_ctrl(0);
    nrf_tx_buf[0] = NRF24L0X_WR_TX_PLOAD;
    memcpy(&nrf_tx_buf[1], txbuf, TX_PLOAD_WIDTH);
    nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, TX_PLOAD_WIDTH + 1);
    nrf24l0x_ce_ctrl(1);

    while (nrf24l0x_irq_pin_get() != 0);   // 等待发送完成

    status = nrf24l0x_status_get();   // 读取状态寄存器的值
    nrf24l0x_status_clr(status);      // 清除TX_DS或MAX_RT中断标志

    // 达到最大重发次数
    if (status & MAX_TX) {
        nrf_tx_buf[0] = NRF24L0X_FLUSH_TX;
        nrf_tx_buf[1] = 0xFF;
        nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, 2);   // 清除RX FIFO寄存器
        NRF24L0X_LOG_INFO("TX Max Clr ok!");
        return MAX_TX;
    }

    // 发送完成
    if (status & TX_OK) {
        NRF24L0X_LOG_INFO("send ok!");
        return TX_OK;
    }

    return 0xFF;   // 其他原因发送失败
}

nrf24l0x_mode_type_e nrf24l0x_working_mode_get(void)
{
    return nrf24l0x_device.working_mode;
}

void nrf24l0x_working_mode_set(nrf24l0x_mode_type_e mode)
{

}

int32_t nrf24l0x_init(const nrf24l0x_device_t *dev, nrf24l0x_reg_init_table_t *init_table, uint8_t table_num)
{
    nrf24l0x_device.working_mode = dev->working_mode;
    nrf24l0x_device.rx_addr      = dev->rx_addr;
    nrf24l0x_device.tx_addr      = dev->tx_addr;

    memset(nrf_tx_buf, 0xFF, sizeof(nrf_tx_buf));
    memset(nrf_rx_buf, 0, sizeof(nrf_rx_buf));

    nrf24l0x_ce_ctrl(0);

    nrf_tx_buf[0] = NRF24L0X_WRITE_REG + TX_ADDR;
    memcpy(&nrf_tx_buf[1], nrf24l0x_device.tx_addr, TX_ADR_WIDTH);
    nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, RX_ADR_WIDTH + 1);   // 写TX节点地址

    nrf_tx_buf[0] = NRF24L0X_WRITE_REG + RX_ADDR_P0;
    memcpy(&nrf_tx_buf[1], nrf24l0x_device.rx_addr, RX_ADR_WIDTH);
    nrf24l0x_transfer_data(nrf_tx_buf, nrf_rx_buf, RX_ADR_WIDTH + 1);   // 设置RX节点地址,主要为了使能ACK

    for (uint8_t i = 0; i < table_num; i++) {
        nrf24l0x_transfer_data((uint8_t *)&init_table[i].reg, nrf_rx_buf, 2);
    }

    // CE为高大于10us,则启动发送.
    nrf24l0x_ce_ctrl(1);

    return 0;
}

